/*
 * UdpPsMediaCaster.h
 *
 *  Created on: 2016年8月24日
 *      Author: zhengboyuan
 */

#ifndef UDPTSMEDIACASTER_H_
#define UDPTSMEDIACASTER_H_

#include "PsMediaCaster.h"
#include "TThread.h"
#include "TCriticalSection.h"
#include "TByteBuffer.h"
#include "MediaPacketQueue.h"
#include "NetAddress.h"
#include "Socket.h"
#include "PSMuxer.h"
#include "PsCaster.h"
#include "H264PropDetector.h"
#include "NaluJoiner.h"
#include "CRtpPackager.h"

namespace av
{

typedef std::deque< NetAddress >        NetAddressArray;
typedef std::shared_ptr< PSMuxer >		PsMuxerPtr;


class UdpPsMediaCaster : public PsMediaCaster, public MediaSink, public RtpPackagerSink, public comn::Thread
{
public:
	UdpPsMediaCaster();
	virtual ~UdpPsMediaCaster();

	virtual int open(const std::string& ip, uint16_t port, const MediaFormat& fmt);

	virtual void close();

	virtual bool isOpen();

	virtual void setID(int id);

	virtual int getID();

	virtual bool addTarget(const std::string& ip, uint16_t port);

	virtual void removeTarget(const std::string& ip, uint16_t port);

	virtual size_t getTargetCount();

	virtual void removeAllTarget();

	virtual bool write(int type, uint8_t* data, int size, int64_t pts, int duration, int flags);

	virtual bool write(av::MediaPacketPtr& pkt);

    virtual void onMediaFormat(const MediaFormat& fmt);

    virtual void onMediaPacket(MediaPacketPtr& pkt);

    virtual void onMediaEvent(int event);


protected:
    virtual int run();
    virtual void doStop();

    virtual void writePacket(uint8_t* data, int size, int64_t pts, int flags);

	virtual void onSlicePacket(const RtpPacket& pkt);

protected:
	void handleMediaPacket(MediaPacketPtr& pkt);

    bool openSocket(const std::string& ip, int port);
    void closeSocket();

    void sendPacket(uint8_t* data, int size);

    bool sendPacket(NetAddress& addr, uint8_t* data, int size);

    void timedwait(int ms);

    int detectKeyFrame(uint8_t* data, int size);

protected:
	comn::Socket    m_socket;

	NetAddress	m_addr;
	MediaPacketQueue    m_pktQueue;

	NetAddressArray		m_targets;
	comn::CriticalSection	m_cs;

	int		m_id;

	PsMuxerPtr	m_muxer;
	int		m_delayCount;

	int64_t	m_videoLastPts;
	int64_t m_audioLastPts;

	H264PropDetector	m_propDetector;
	std::shared_ptr< NaluJoiner >	m_naluJoiner;

	MediaFormat	m_format;

	CRtpPackager	m_packager;

};



} /* namespace av */

#endif /* UDPTSMEDIACASTER_H_ */
